﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Scrabble.Model.Events
{
    internal class PlayedWordEvent : GameEvent, IPlayWordEvent
    {
        public PlayedWordEvent(IPlayer player, IEnumerable<TileInPlay> play, int score, IEnumerable<Tile> tiles)
            : base(player, score, tiles)
        {
            Play = play.ToArray();
            Description = NotationFromPlay;
        }

        public TileInPlay[] Play
        {
            get; private set;
        }

        public bool PlayedAcross
        {
            get { return PlayVector.IsAcross; }
        }

        public PlayVector PlayVector
        {
            get
            {
                var vector = new PlayVector { StartingLocation = Play.First().Location, Length = Play.Length };
                var nextTile = Play.Skip(1).FirstOrDefault();

                if (nextTile != null)
                    vector.IsAcross = nextTile.Location.Row == vector.StartingLocation.Row;

                return vector;
            }
        }

        public string NotationFromPlay
        {
            get
            {
                var result = new StringBuilder();
                var inExistingSequence = false;

                foreach (var tileInPlay in Play)
                {
                    if (MovedTiles.Contains(tileInPlay.Tile))
                    {
                        if (inExistingSequence)
                        {
                            result.Append(')');
                            inExistingSequence = false;
                        }

                        result.Append(tileInPlay.Tile.InitiallyBlank
                            ? Char.ToLower(tileInPlay.Tile.Letter)
                            : Char.ToUpper(tileInPlay.Tile.Letter));
                    }
                    else
                    {
                        if (!inExistingSequence)
                        {
                            result.Append('(');
                            inExistingSequence = true;
                        }

                        result.Append(tileInPlay.Tile.Letter);
                    }
                }

                if (inExistingSequence) 
                    result.Append(')');

                return result.ToString();
            }
        }

        public override string ToNotation()
        {
            return String.Format("{0} {1}", PlayVector, NotationFromPlay);
        }

        protected override string TypeOfAction
        {
            get { return ActionType.Play; }
        }
    }
}